package xpn.platform.modules.sys.permission;

import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import xpn.platform.common.rulesengine.SimpleRulesEngine;
import xpn.platform.common.rulesengine.SimpleRulesEngine.InjectedObject;
import xpn.platform.modules.sys.role.SysRole;
import xpn.platform.modules.sys.user.SysUser;
import xpn.platform.modules.sys.user.SysUserService;

import javax.script.ScriptException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class SysPermissionServiceImpl implements SysPermissionService {

	// 判断当前用户是否拥有角色的函数
	private static String hasRoleFunc = "function hasRole(roleName) {var roles = xpnCurUserRoles;if (!roles) return false;for (var i=0;i<roles.length;i++) {if (roles[i].name == roleName) return true;};return false;} ";
	// 返回当前用户ou的函数
	private static String ouFunc = "function ou(level) {if (!xpnCurUserOrg) return ''; var names=xpnCurUserOrg.split('/');var len=names.length;if (level>=len) return '';return names[len-level-1];} ";
	// 取关联对象属性
	private static String linkAttrFunc = "function linkAttr(record, attr) {if (!record || !record._embedded) return null;return record._embedded[attr];}";

	// 判断实体对象的创建人的角色
	private static String hasRoleInCreatedByFunc = "function hasRoleInCreatedBy(record,roleName) {if (!record || !record.roleList) return false; "
			+ "var roleList=record.roleList;for (var i=0;i<roleList.length;i++) {if (roleList[i] == roleName||roleList[i].name == roleName) return true;} return false;}";

	@Autowired
	Gson gson;

	@Autowired
	private SysPermissionDAO permissionDao;

	@Autowired
	private SysUserService userService;

	@Autowired
	private SimpleRulesEngine simpleRulesEngine;

	@Autowired
	private RestTemplate restTemplate;

	@Override
	public Set<String> getUserPermissions(SysUser user) throws ScriptException {
		// 1 获取所有授权列表
		List<SysPermission> permissionList = permissionDao.findAll();

		// 2 构造注入变量
		InjectedObject varUser = new InjectedObject(user, "xpnCurUser"); // 当前用户
		InjectedObject varRoles = new InjectedObject(new ArrayList<SysRole>(user.getRoles()), "xpnCurUserRoles"); // 当前用户的角色
		InjectedObject varOrg = new InjectedObject(userService.getOrgFullName(user), "xpnCurUserOrg"); // 当前用户所属机构全名
		simpleRulesEngine.injectObjects(varUser, varRoles, varOrg);

		// 3 注入函数
		simpleRulesEngine.executeRule(hasRoleFunc);
		simpleRulesEngine.executeRule(ouFunc);

		// 4 检测所有的授权的拥有规则，成立则加入用户获得的授权列表
		Set<String> permissions = new HashSet<String>();

		for (SysPermission permission : permissionList) {
			String rule = permission.getAuthorizationRule();
			if (simpleRulesEngine.isTrue(rule)) {
				permissions.add(permission.getNo());
			}
		}

		// 4 返回用户获得的授权列表
		return permissions;
	}

	@Override
	public List<CheckPermissionRequest.Rule> checkPermission(CheckPermissionRequest request) throws ScriptException {
		List<CheckPermissionRequest.Rule> rules = new ArrayList<CheckPermissionRequest.Rule>();
		if (request == null) {
			return rules;
		}

		// 1 注入变量
		SysUser curUser = userService.getSessionUser();
		InjectedObject varUser = new InjectedObject(curUser, "xpnCurUser"); // 当前用户
		InjectedObject varRoles = new InjectedObject(new ArrayList<SysRole>(curUser.getRoles()), "xpnCurUserRoles"); // 当前用户的角色
		InjectedObject varOrg = new InjectedObject(userService.getOrgFullName(curUser), "xpnCurUserOrg"); // 当前用户所属机构全名
		simpleRulesEngine.injectObjects(varUser, varRoles, varOrg);

		// 2 注入实体对象
		for (CheckPermissionRequest.InjectedEntity injectedEntity : request.getInjectedEntities()) {
			try {
				//System.out.println(injectedEntity.getHref());
				//特殊处理 zyk 20220629
				String href=injectedEntity.getHref();
				URI uri=URI.create(href);
				String  host=uri.getHost();
				href=href.replaceAll(host,"localhost");
				Object entity = restTemplate.getForObject(href, Object.class);
				//endOf特殊处理 zyk 20220629
				simpleRulesEngine.injectObjects(new InjectedObject(entity, injectedEntity.getRefVarName()));
			} catch (RestClientException e) {
				e.printStackTrace();
			}
			// 注入实体对象的创建人
			if (!injectedEntity.getCreatedByHref().equals("")) {
				try {
					Object entity = restTemplate.getForObject(injectedEntity.getCreatedByHref(), Object.class);
					simpleRulesEngine
							.injectObjects(new InjectedObject(entity, injectedEntity.getRefVarName() + "CreatedBy"));
				} catch (RestClientException e) {
					e.printStackTrace();
				}
			}
		}

		// 3 注入函数
		if (request.isHasRoleFunc()) {
			simpleRulesEngine.executeRule(hasRoleFunc);
		}
		if (request.isOuFunc()) {
			simpleRulesEngine.executeRule(ouFunc);
		}
		if (request.isLinkAttrFunc()) {
			simpleRulesEngine.executeRule(linkAttrFunc);
			simpleRulesEngine.executeRule(hasRoleInCreatedByFunc);
		}

		// 4 检测所有的授权，成立则加入个体返回结果列表
		for (CheckPermissionRequest.Rule rule : request.getRules()) {
			if (simpleRulesEngine.isTrue(rule.getRule())) {
				rules.add(rule);
			}
		}

		// 4 返回用户获得的授权列表
		return rules;
	}
}
